/*
 * DisplayControl.c
 *
 *  Created on: 22.09.2011
 *      Author: windows97
 */

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "Globals.h"
#include "HwAbstraction.h"
#include "lcd.h"
#include "DisplayControl.h"

#if( DISP_HEIGHT != LCD_LINES )
  #error DISP_HEIGHT != LCD_LINES
#endif

#if( DISP_WIDTH != LCD_DISP_LENGTH )
#error DISP_WIDTH != LCD_DISP_LENGTH
#endif


static uint8_t gDispState_u8 = DispOff;
static volatile uint8_t gDispDimUpDown_u8 = 0;

#define DISP_MIN_LIGHT_U8 ((uint8_t) (0U))
#define DISP_MAX_LIGHT_U8 ((uint8_t) (100U))


void DispInit( void )
{
  lcd_init(LCD_DISP_ON);
  /* User defined icons */
  lcd_command(0x40);
  /* Radio tower */
  lcd_putc(145);
  lcd_putc(138);
  lcd_putc(149);
  lcd_putc(132);
  lcd_putc(132);
  lcd_putc(132);
  lcd_putc(132);
  lcd_putc(142);
  /* Alarm bell */
  lcd_putc(128);
  lcd_putc(132);
  lcd_putc(142);
  lcd_putc(142);
  lcd_putc(142);
  lcd_putc(159);
  lcd_putc(132);
  lcd_putc(128);
  /* Box with cross (e.g. for checked alarm)*/
  lcd_putc(31);
  lcd_putc(17);
  lcd_putc(27);
  lcd_putc(21);
  lcd_putc(27);
  lcd_putc(17);
  lcd_putc(31);
  lcd_putc(0);
  /* Box without cross (e.g. for unchecked alarm) */
  lcd_putc(31);
  lcd_putc(17);
  lcd_putc(17);
  lcd_putc(17);
  lcd_putc(17);
  lcd_putc(17);
  lcd_putc(31);
  lcd_putc(0);

  /* init backlight dimming */
  TCCR0A = (1 << WGM01) | (1 << WGM00) | (1 << COM0A1); /* FAST PWM - Clear OC0A on compare match, set OC0A at BOTTOM, (non-inverting mode) */
  TCCR0B = (1 << CS02) | (0 << CS01) | (0<<CS00);
  gDispDimUpDown_u8 = DISP_MIN_LIGHT_U8;
  OCR0A = gDispDimUpDown_u8;
  gDispState_u8 = DispOff;
}

void DispSetState( uint8_t iOnOff, T_DispSwitchBehavior iBehavior_t)
{
  if( ( DispOn  == iOnOff        ) &&
      ( DispOff == gDispState_u8 ) )
  {
    gDispState_u8 = DispOn;
    if( DispFast == iBehavior_t )
    {
      gDispDimUpDown_u8 = DISP_MAX_LIGHT_U8;
    }
    else
    {
      /* let's dim up smooth */
      TIMSK0 |= ( 1 << TOIE0 );
    }
  }
  else if( ( DispOff == iOnOff        ) &&
           ( DispOn  == gDispState_u8 ) )
  {
    gDispState_u8 = DispOff;
    if( DispFast == iBehavior_t )
    {
      gDispDimUpDown_u8 = DISP_MIN_LIGHT_U8;
    }
    else
    {
      /* let's dim down smooth */
      TIMSK0 |= ( 1 << TOIE0 );
    }
  }
}

uint8_t DispGetState( void )
{
  return (gDispState_u8);
}

void DispToggleState( T_DispSwitchBehavior iBehavior_t )
{
  if ( DispOff == gDispState_u8 )
  {
    DispSetState( DispOn, iBehavior_t );
  }
  else
  {
    DispSetState( DispOff, iBehavior_t );
  }
}

ISR(TIMER0_OVF_vect)
{
  if( DispOn == gDispState_u8 )
  {
    if( DISP_MAX_LIGHT_U8 > gDispDimUpDown_u8 )
    {
      OCR0A = ++gDispDimUpDown_u8;
    }
    else
    {
      TIMSK0 &= ~( 1 << TOIE0 );
    }
  }
  else
  {
    if( DISP_MIN_LIGHT_U8 < gDispDimUpDown_u8 )
    {
      OCR0A = --gDispDimUpDown_u8;
    }
    else
    {
      TIMSK0 &= ~( 1 << TOIE0 );
    }
  }
}
